home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1987 */
- /* David Palmer */
- /* Mail code 220-47 */
- /* California Institute Of Technology */
- /* Uses EasyDialog.c (also ⌐ 1987 By David Palmer) */
- /* Duplication, modification, and examination allowed on a */
- /* non-commercial basis only. Commercial use prohibited */
- /* without prior written agreement with the author. (This */
- /* includes sale by for-profit companies, and use as an */
- /* inducement to buy something.) */
-
- #include <quickdraw.h>
- #include <WindowMgr.h>
- #include "orbit.h"
- #include <EventMgr.h>
-
- #include <stdio.h>
-
- #define G 6.67e-11 /* MKS */
- #define NMAX 100 /* how many particles */
- #define TRUE (-1)
- #define FALSE 0
-
- #define HUGE 1e4000
- double sqrt();
-
- double precision = 100;
- double drawperiod = 86400;
- double scale = 2083333333;
- int trailstyle = 3;
- int fcenter = TRUE;
- int background = 1;
-
- PARTICLE rgpa[NMAX]; /* All of the particles */
-
- int cpa; /* number of particles */
- int cparead;
- int xzero;
- int yzero;
- int drawcode, erasecode;
-
- double dt = 864;
- double rmin;
- double v2max;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- InitGraf (&thePort); /* initialize the screen */
- InitFonts();
- InitWindows();
- InitMenus();
- InitCursor(); /* make the arrow Cursor */
- TEInit();
- InitDialogs(0L);
-
- DoIt();
- }
-
- CenterParticles(ppa, cpa)
- PARTICLE *ppa;
- int cpa;
- {
- int i, j;
- double p[NDIMS]; /* total momentum */
- double mx[NDIMS]; /* first moment */
- double m=0;
-
- for (j = 0 ; j < NDIMS ; j++) {
- p[j] = 0;
- mx[j] = 0;
- }
- for (i = 0 ; i < cpa ; i++) {
- m += ppa[i].m;
- for (j = 0 ; j < NDIMS ; j++) {
- mx[j] += ppa[i].m * ppa[i].x[j];
- p[j] += ppa[i].p[j];
- }
- }
- if (m == 0) /* can happen with negative and positive masses */
- return;
- for (j = 0 ; j < NDIMS ; j++) {
- mx[j] /= m;
- p[j] /= m; /* velocity of center of mass */
- }
- for (i = 0; i < cpa ; i++)
- for (j = 0 ; j < NDIMS ; j++) {
- ppa[i].x[j] -= mx[j];
- ppa[i].p[j] -= ppa[i].m * p[j];
- ppa[i].xt[j] = ppa[i].x[j];
- }
- }
-
-
- SetPoint(ppa)
- PARTICLE *ppa;
- {
- ppa->pt.h = xzero + ppa->x[0] / scale;
- ppa->pt.v = yzero - ppa->x[1] / scale;
- }
-
- Interact(ppa1, ppa2)
- PARTICLE *ppa1, *ppa2;
- {
- float ftot, f[NDIMS];
- double r2, r;
- double d[NDIMS];
- int i;
-
- r2 = 0;
- for (i = 0 ; i < NDIMS ; i++) {
- d[i] = ppa1->xt[i] - ppa2->xt[i];
- r2 += d[i]*d[i];
- }
-
- r = sqrt(r2);
- if (rmin > r)
- rmin = r;
- ftot = G * ppa1->m * ppa2->m / r2;
- for (i = 0 ; i < NDIMS ; i++) {
- f[i] = ftot * d[i]/r;
- ppa1->f[i] -= f[i];
- ppa2->f[i] += f[i];
- }
- }
-
- Propagate(ppa, odt, dt)
- PARTICLE *ppa;
- double odt, dt;
- {
- double v, a;
- double step, sesquistep, step2, sesquistep2;
- double v2;
- int i;
-
- step = odt; step2 = 0.5 * odt *odt;
- sesquistep = odt + 0.5 * dt; sesquistep2 = 0.5*sesquistep*sesquistep;
-
- v2 = 0;
- for (i = 0 ; i < NDIMS ; i++) {
- v = ppa->p[i] / ppa->m;
- a = ppa->f[i] / ppa->m;
- ppa->xt[i] = ppa->x[i] + (sesquistep * v) + sesquistep2 * a;
- ppa->x[i] += (step * v) + step2 * a;
- ppa->p[i] += step * ppa->f[i];
- ppa->f[i] = 0;
- v2 += v*v;
- }
-
- if (v2max < v2)
- v2max = v2;
- }
-
- DrawPath(ppa)
- PARTICLE *ppa;
- {
- switch (trailstyle) {
- case dot:
- PenMode(erasecode);
- MoveTo(ppa->pt.h, ppa->pt.v);
- LineTo(ppa->pt.h, ppa->pt.v); /* Keep going */
- case dottrain:
- PenMode(drawcode);
- SetPoint(ppa);
- MoveTo(ppa->pt.h, ppa->pt.v);
- LineTo(ppa->pt.h, ppa->pt.v);
- break;
- case linetrail:
- MoveTo(ppa->pt.h, ppa->pt.v);
- PenMode(drawcode);
- SetPoint(ppa);
- LineTo(ppa->pt.h, ppa->pt.v);
- break;
- default:
- break;
- }
- }
-
-
- DoIt()
- {
- int i, j;
- double t, odt;
- static int tlast;
- int fdraw;
- int whichbutton;
- EventRecord theEvent;
-
- xzero = screenBits.bounds.right/2;
- yzero = screenBits.bounds.bottom/2;
-
- while (TRUE) {
- cpa = 0;
- if (0 == GetParams())
- exit(0);
-
- do {
- whichbutton = GetInit(&rgpa[cpa]);
- if (whichbutton != 3) { /* if not the END button */
- cpa++;
- }
- } while (whichbutton == 1);
- if (fcenter)
- CenterParticles(&rgpa, cpa);
- for (i = 0 ; i < cpa ; i++) {
- SetPoint(&rgpa[i]);
- }
- PenNormal();
- PaintRect(&thePort->portRect);
- if (background) { /* background is not black */
- drawcode = notPatCopy;
- erasecode = patCopy;
- } else {
- InvertRect(&thePort->portRect);
- drawcode = patCopy;
- erasecode = notPatCopy;
- }
- PenMode(drawcode);
- HideCursor();
-
- while (!Button()) {
- if (tlast != (int)(t/drawperiod)) {
- tlast = t/drawperiod;
- fdraw = TRUE;
- } else
- fdraw = FALSE;
- rmin = HUGE;
- for (i = 0 ; i < cpa ; i++) {
- for (j = i+1 ; j < cpa ; j++) {
- Interact(&rgpa[i], &rgpa[j]);
- }
- }
- t += dt;
- odt = dt;
- if (v2max != 0 && rmin != HUGE)
- dt = rmin/(sqrt(v2max)*precision);
- if (dt > 2*odt) /* limit growth of timestep */
- dt = 2*odt;
- v2max = 0;
- for (i = 0 ; i < cpa ; i++) {
- Propagate(&rgpa[i], odt, dt);
- if (fdraw)
- DrawPath(&rgpa[i]);
- }
- GetNextEvent(0xffff, &theEvent);
- }
- ShowCursor();
- }
- }